package com.zpark.it.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zpark.it.clients.ProductClient;
import com.zpark.it.mapper.OrderMapper;
import com.zpark.it.param.OrderParam;
import com.zpark.it.param.PageParam;
import com.zpark.it.param.ProductCollectParam;
import com.zpark.it.pojo.Address;
import com.zpark.it.pojo.Order;
import com.zpark.it.pojo.Product;
import com.zpark.it.service.OrderService;
import com.zpark.it.to.OrderToProduct;
import com.zpark.it.utils.R;
import com.zpark.it.vo.AdminOrderVo;
import com.zpark.it.vo.CartVo;
import com.zpark.it.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Or;
import org.aspectj.weaver.ast.Var;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Title: OrderServiceImpl
 * @Author Charles
 * @Package com.zpark.it.service.impl
 * @Date 2023/7/26 16:50
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    /**
     * 进行订单数据保存
     * 1、将购物车数据转成订单数据
     * 2、进行订单数据的批量插入
     * 3、商品库存修改信息
     * 4、发送购物车库存修改信息
     * @param orderParam
     * @return
     */

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ProductClient productClient;

    @Autowired
    private OrderMapper orderMapper;

    @Transactional
    @Override
    public R save(OrderParam orderParam) {
        //准备数据
        List<Integer> cartIds=new ArrayList<>();
        List<OrderToProduct> orderToProducts=new ArrayList<>();
        List<Order> orderList=new ArrayList<>();

        //生成数据
        Integer userId=orderParam.getUserId();
        long orderId = System.currentTimeMillis();

        for (CartVo cartVo : orderParam.getProducts()) {
            cartIds.add(cartVo.getId());//保存删除的购物车项的id
            OrderToProduct orderToProduct=new OrderToProduct();
            orderToProduct.setNum(cartVo.getNum());
            orderToProduct.setProductId(cartVo.getProductID());
            orderToProducts.add(orderToProduct);  //商品服务修改的数据

            Order order=new Order();
            order.setOrderId(orderId);
            order.setOrderTime(orderId);
            order.setUserId(userId);
            order.setProductId(cartVo.getProductID());
            order.setProductNum(cartVo.getNum());
            order.setProductPrice(cartVo.getPrice());

            orderList.add(order);

        }

        //订单数量批量保存
        saveBatch(orderList);

        //发送购物车信息
        rabbitTemplate.convertAndSend("topic.ex","clear.cart",cartIds);

        //发送商品服信息
        rabbitTemplate.convertAndSend("topic.ex","sub.number",orderToProducts);



        return R.ok("订单保存成功！");
    }

    /**
     * 分组查询购物车订单数据
     * 1、查询用户对应的全部订单项
     * 2、利用stream进行订单分组 orderId
     * 3、查询订单的全部商品集合，并stream组成map
     * 4、封装返回的OrderVo对象
     * @param userId
     * @return
     */
    @Override
    public R list(Integer userId) {

        QueryWrapper<Order> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        List<Order> list=list(queryWrapper);

        //分组
        Map<Long, List<Order>> orderMap = list.stream().collect(Collectors.groupingBy(Order::getOrderId));

        //查询商品数据
        List<Integer> productIds = list.stream().map(Order::getProductId).collect(Collectors.toList());

        ProductCollectParam productCollectParam=new ProductCollectParam();
        productCollectParam.setProductIds(productIds);
        List<Product> productList = productClient.cartList(productCollectParam);

        Map<Integer, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getProductId, v -> v));

        //结果封装
        List<List<OrderVo>> result=new ArrayList<>();

        //遍历订单项集合
        for (List<Order> orders : orderMap.values()) {

            //封装每一个订单
            List<OrderVo> orderVos=new ArrayList<>();

            for (Order order : orders) {
                OrderVo orderVo=new OrderVo();
                BeanUtils.copyProperties(order,orderVo);
                Product product = productMap.get(order.getProductId());
                orderVo.setProductName(product.getProductName());
                orderVo.setProductPicture(product.getProductPicture());
                orderVos.add(orderVo);
            }

            result.add(orderVos);
        }

        R r = R.ok("订单数据获取成功", result);
        return r;
    }

    /**
     * 检查订单中是否有商品被引用
     *
     * @param productId
     * @return
     */
    @Override
    public R check(Integer productId) {
        QueryWrapper<Order> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("product_id",productId);

        Long count = baseMapper.selectCount(queryWrapper);

        if (count>0) {
            return R.fail("订单中有"+count+"件商品引用");
        }

        return R.ok("无订单引用，可以删除");
    }

    /**
     * 后台管理查询订单数据
     *
     * @param pageParam
     * @return
     */
    @Override
    public R adminList(PageParam pageParam) {
        //分页参数计算完毕
        int offset=(pageParam.getCurrentPage()-1)* pageParam.getPageSize();
        int pageSize=pageParam.getPageSize();

        List<AdminOrderVo> adminOrderVoList=orderMapper.selectAdminOrder(offset,pageSize);


        return R.ok("订单数据查询成功",adminOrderVoList);
    }
}
